package com.zhz.controller;

import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhz.domain.User;
import com.zhz.domain.UserAuthAuditRecord;
import com.zhz.domain.UserAuthInfo;
import com.zhz.dto.UserDto;
import com.zhz.model.*;
import com.zhz.service.UserAuthAuditRecordService;
import com.zhz.service.UserAuthInfoService;
import com.zhz.service.UserService;
import com.zhz.vo.UserAuthInfoVo;
import com.zhz.feign.UserServiceFeign;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @author ：zhz
 * @date ：Created in 2021/01/02
 * @version: V1.0
 * @slogan: 天下风云出我辈，一入代码岁月催
 * @description:
 **/
@RestController
@RequestMapping("/users")
@Api(tags = "会员的管理")
public class UserController implements UserServiceFeign {

    @Autowired
    private UserService userService;
    @Autowired
    private UserAuthInfoService userAuthInfoService;
    @Autowired
    private UserAuthAuditRecordService userAuthAuditRecordService;

    @GetMapping
    @ApiOperation(value = "查询会员信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "current", value = "当前页"),
            @ApiImplicitParam(name = "size", value = "每页显示的条数"),
            @ApiImplicitParam(name = "mobile", value = "手机号"),
            @ApiImplicitParam(name = "userId", value = "会员的ID，精确查询"),
            @ApiImplicitParam(name = "userName", value = "会员的名称"),
            @ApiImplicitParam(name = "realName", value = "会员的真实姓名"),
            @ApiImplicitParam(name = "status", value = "会员的状态")
    })
    @PreAuthorize("hasAuthority('user_query')")
    public R<Page<User>> findByPage(@ApiIgnore Page<User> page,
                                    String mobile,
                                    Long userId,
                                    String userName,
                                    String realName,
                                    Integer status
    ) {
        page.addOrder(OrderItem.desc("last_update_time"));
        return R.ok(userService.findByPage(page, mobile, userId, userName, realName, status, null));
    }

    @PatchMapping
    @ApiOperation(value = "修改用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user", value = "会员信息")
    })
    @PreAuthorize("hasAuthority('user_update')")
    public R updateUser(@RequestBody @Validated User user) {
        return userService.updateById(user) == true ? R.ok("更新成功") : R.fail("更新失败");
    }

    @PostMapping("/status")
    @ApiOperation(value = "修改用户状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "会员id"),
            @ApiImplicitParam(name = "status", value = "会员的状态")
    })
    @PreAuthorize("hasAuthority('user_update')")
    public R updateStatus(Long id, Byte status) {
        User user = new User();
        user.setId(id);
        user.setStatus(status);
        return userService.updateById(user) == true ? R.ok("更新成功") : R.fail("更新失败");
    }

    @PostMapping("/info")
    @ApiOperation(value = "获取用户的详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "会员id")
    })
    public R<User> userInfo(Long id) {
        return R.ok(userService.getById(id));
    }

    @GetMapping("/directInvites")
    @ApiOperation(value = "查询该用户邀请的用户列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "current", value = "当前页"),
            @ApiImplicitParam(name = "size", value = "每页显示的条数"),
            @ApiImplicitParam(name = "userId", value = "该用户的id‘")
    })
    public R<Page<User>> getDirectInvites(@ApiIgnore Page<User> page, Long userId) {
        return R.ok(userService.findDirectInvitePage(page, userId));
    }

    @GetMapping("/auths")
    @ApiOperation(value = "查询用户的审核列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "current", value = "当前页"),
            @ApiImplicitParam(name = "size", value = "每页显示的条数"),
            @ApiImplicitParam(name = "mobile", value = "会员的手机号"),
            @ApiImplicitParam(name = "userId", value = "会员的Id,精确查询"),
            @ApiImplicitParam(name = "userName", value = "会员的名称"),
            @ApiImplicitParam(name = "realName", value = "会员的真实名称"),
            @ApiImplicitParam(name = "reviewsStatus", value = "会员的状态")

    })
    public R<Page<User>> findUserAuths(
            @ApiIgnore Page<User> page,
            String mobile,
            Long userId,
            String userName,
            String realName,
            Integer reviewsStatus
    ) {
        return R.ok(userService.findByPage(page, mobile, userId, userName, realName, null, reviewsStatus));
    }

    /**
     * 差询用户的认证详情
     * {
     * user:
     * userAuthInfoList:[]
     * userAuditRecordList:[]
     * }
     */
    @GetMapping("/auth/info")
    @ApiOperation(value = "查询用户的认证详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户的Id")
    })
    public R<UserAuthInfoVo> getUserAuthInfo(Long id) {
        User user = userService.getById(id);
        List<UserAuthInfo> userAuthInfoList = null;
        List<UserAuthAuditRecord> userAuthAuditRecordList = null;
        //用户不为空
        if (!StringUtils.isEmpty(user)) {
            //用户的审核记录
            Integer reviewsStatus = user.getReviewsStatus();
            if (reviewsStatus == null || reviewsStatus == 0) {//待审核
                userAuthAuditRecordList = Collections.emptyList();// 用户没有审核记录
                userAuthInfoList = userAuthInfoService.getUserAuthInfoByUserId(id);
            } else {
                userAuthAuditRecordList = userAuthAuditRecordService.getUserAuthAuditRecordList(id);
                // 1、查询用户的认证详情列表-> 用户的身份信息
                // 1.1之前我们查询时,是按照认证的日志排序的,第0 个值,就是最近被认证的一个值
                UserAuthAuditRecord userAuthAuditRecord = userAuthAuditRecordList.get(0);
                // 1.2、认证的唯一标识
                Long authCode = userAuthAuditRecord.getAuthCode();
                userAuthInfoList = userAuthInfoService.getUserAuthInfoByCode(authCode);
            }
        }
        return R.ok(new UserAuthInfoVo(user, userAuthInfoList, userAuthAuditRecordList));
    }

    @PostMapping("/auths/status")
    @ApiOperation(value = "用户审核--在于对一组图片(唯一Code)的认可,符合条件,审核通过")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户的ID"),
            @ApiImplicitParam(name = "authStatus", value = "用户的审核状态"),
            @ApiImplicitParam(name = "authCode", value = "一组图片的唯一标识"),
            @ApiImplicitParam(name = "remark", value = "审核拒绝的原因"),
    })
    public R updateUserAuthStatus(@RequestParam(required = true) Long id, @RequestParam(required = true) Byte authStatus, @RequestParam(required = true) Long authCode, String remark) {
        // 审核: 1 修改user 里面的reviewStatus
        // 2 在authAuditRecord 里面添加一条记录
        userService.updateUserAuthStatus(id, authStatus, authCode, remark);
        return R.ok();
    }

    @GetMapping("/current/info")
    @ApiOperation(value = "获取当前登录用户对象的信息")
    public R<User> currentUserInfo() {
        String idStr = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        User user = userService.getById(Long.valueOf(idStr));
        user.setPassword("***");
        user.setPaypassword("***");
        user.setAccessKeyId("***");
        user.setAccessKeySecret("***");
        return R.ok(user);
    }


    @PostMapping("/authAccount")
    @ApiOperation(value = "用户的实名认证")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userAuthForm", value = "userAuthFormjson数据")
    })
    public R identifyCheck(@RequestBody UserAuthForm userAuthForm) {
        String idStr = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        boolean isOk = userService.identifyVerify(Long.valueOf(idStr), userAuthForm);
        return isOk == true ? R.ok() : R.fail("认证失败");
    }

    @PostMapping("/authUser")
    @ApiOperation(value = "用户的高级认证")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "imgs", value = "用户的图片地址")
    })
    public R authUser(@RequestBody String[] imgs) {
        String idStr = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        userService.authUser(Long.parseLong(idStr), Arrays.asList(imgs));
        return R.ok();
    }

    @PostMapping("/updatePhone")
    @ApiOperation(value = "修改用户号码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "updatePhoneParam", value = "修改用户手机号码的参数")
    })
    public R updatePhone(@RequestBody @Validated UpdatePhoneParam updatePhoneParam) {
        String idStr = SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString();
        boolean isOk = userService.updatePhone(Long.parseLong(idStr), updatePhoneParam);

        return isOk == true ? R.ok() : R.fail("修改失败");
    }

    @PostMapping("/checkTel")
    @ApiOperation(value = "检查新的号码是否可用，若可用，则给该新手机号码发送验证码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "mobile", value = "新的手机号码"),
            @ApiImplicitParam(name = "countryCode", value = "手机号码的区域")
    })
    public R checkNewPhone(@RequestParam(required = true) String mobile, @RequestParam(required = true) String countryCode) {
        boolean isOk = userService.checkNewPhone(mobile, countryCode);
        return isOk == true ? R.ok() : R.fail("新的手机号码不存在");
    }

    @PostMapping("/updateLoginPassword")
    @ApiOperation(value = "修改用户的登录密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "updateLoginParam", value = "修改密码参数")
    })
    public R updateLoginPassword(@RequestBody @Validated UpdateLoginParam updateLoginParam) {
        Long userId = Long.parseLong(SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
        boolean isOk = userService.updateLoginPassword(userId, updateLoginParam);
        return isOk == true ? R.ok() : R.fail("修改密码失败");
    }

    @PostMapping("/updatePayPassword")
    @ApiOperation(value = "修改用户的交易密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "updateLoginParam", value = "修改密码参数")
    })
    public R updatePayPassword(@RequestBody @Validated UpdateLoginParam updateLoginParam) {
        Long userId = Long.parseLong(SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
        boolean isOk = userService.updatePayPassword(userId, updateLoginParam);
        return isOk == true ? R.ok() : R.fail("修改交易密码失败");
    }

    @PostMapping("/setPayPassword")
    @ApiOperation(value = "重新设置交易密码")
    public R setPayPassword(@RequestBody @Validated UnsetPayPasswordParam unsetPayPasswordParam) {
        Long userId = Long.valueOf(SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
        boolean isOk = userService.unsetPayPassword(userId, unsetPayPasswordParam);
        return isOk == true ? R.ok() : R.fail("重置失败");
    }


    @GetMapping("/invites")
    @ApiOperation(value = "用户的邀请列表")
    public R<List<User>> getUserInvites() {
        Long userId = Long.valueOf(SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
        List<User> users = userService.getUserInvites(userId);
        return R.ok(users);
    }


    @PostMapping("/register")
    @ApiOperation(value = "用户的注册")
    public R register(@RequestBody RegisterParam registerParam) {
        boolean isOk = userService.register(registerParam);
        return isOk == true ? R.ok() : R.fail("注册失败");
    }


    @PostMapping("/setPassword")
    @ApiOperation(value = "用户重置密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "unSetPasswordParam", value = "unSetPasswordParam json")
    })
    public R unsetPassword(@RequestBody @Validated UnSetPasswordParam unSetPasswordParam) {
        boolean isOk = userService.unsetLoginPwd(unSetPasswordParam);
        return isOk == true ? R.ok() : R.fail("重置失败");
    }
    /**
     * 用于admin-service 里面远程调用member-service
     *
     * @param ids
     * @return
     */
    @Override
    public Map<Long, UserDto> getBasicUsers(List<Long> ids, String userName, String mobile) {
        Map<Long, UserDto> userDtos = userService.getBasicUsers(ids,  userName,  mobile);
        return userDtos;
    }
}
